;;; init-lsp-bridge.el --- configuration for lsp-bridge -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:

(setq acm-enable-capf t)
(with-eval-after-load 'lsp-bridge
  (setq lsp-bridge-enable-signature-help t)
  (setq lsp-bridge-signature-show-function #'lsp-bridge-signature-show-with-frame)
  (setq lsp-bridge-signature-show-with-frame-position "point")

  (define-key lsp-bridge-mode-map (kbd "M-l n") #'lsp-bridge-diagnostic-jump-next)
  (define-key lsp-bridge-mode-map (kbd "M-l p") #'lsp-bridge-diagnostic-jump-prev)
  (define-key lsp-bridge-mode-map (kbd "M-l l") #'lsp-bridge-diagnostic-list)
  (define-key lsp-bridge-mode-map (kbd "M-l d") #'lsp-bridge-popup-documentation)


  (defun ctrlwei/override-CAP (&rest args)
    (cl-letf (((symbol-function #'completion-at-point) #'lsp-bridge-popup-complete-menu))
      (apply args)))

  (advice-add #'lsp-bridge--enable :after (lambda ()
                                            (when lsp-bridge-mode
                                              (corfu-mode -1)
                                              (advice-add #'indent-for-tab-command :around #'ctrlwei/override-CAP))))
  (advice-add #'lsp-bridge--disable :after (lambda ()
                                             (corfu-mode 1)
                                             (advice-remove #'indent-for-tab-command  #'ctrlwei/override-CAP)))


  ;; lsp-bridge work with xref-find-definitions
  (require 'xref)
  (defun ctrlwei/find-definitions-with-lsp-bridge ()
    (interactive)
    (if (and lsp-bridge-mode (not (memq major-mode '(emacs-lisp-mode lisp-interaction-mode))))
        (lsp-bridge-find-def)
      (call-interactively 'xref-find-definitions)))
  (add-to-list 'xref-prompt-for-identifier #'ctrlwei/find-definitions-with-lsp-bridge 'append)
  (advice-add #'lsp-bridge-define--jump :around (lambda (&rest args) (xref--push-markers (current-buffer) (point)) (apply args)))
  (define-key lsp-bridge-mode-map (kbd "M-.") #'ctrlwei/find-definitions-with-lsp-bridge)

  ;; scroll lsp-bridge popup document window
  (setq ctrlwei-lsp-bridge-popup-doc-mode-map
        (let ((map (make-sparse-keymap)))
          ;; see `lsp-bridge-monitor-post-command', this-command string must start with "lsp-bridge-popup-documentation-scroll"
          (define-key map (kbd "<escape>") #'lsp-bridge-popup-documentation-scroll--hide-doc-tooltip)
          (define-key map (kbd "<f2>") #'lsp-bridge-popup-documentation-scroll-up)
          (define-key map (kbd "<f3>") #'lsp-bridge-popup-documentation-scroll-down)
          map))

  (define-minor-mode ctrlwei-lsp-bridge-popup-doc-mode
    ""
    :keymap ctrlwei-lsp-bridge-popup-doc-mode-map
    :init-value nil)

  (defun lsp-bridge-popup-documentation-scroll--hide-doc-tooltip ()
    (interactive)
    (lsp-bridge-hide-doc-tooltip))

  (defun ctrlwei/lsp-bridge-popup-documentation-advice (&rest args)
    (ctrlwei-lsp-bridge-popup-doc-mode 1))

  (defun ctrlwei/lsp-bridge-hide-doc-tooltip-advice (&rest args)
    (ctrlwei-lsp-bridge-popup-doc-mode -1))

  (advice-add 'lsp-bridge-popup-documentation--callback :after #'ctrlwei/lsp-bridge-popup-documentation-advice)
  (advice-add 'lsp-bridge-hide-doc-tooltip :after #'ctrlwei/lsp-bridge-hide-doc-tooltip-advice)

  )

(with-eval-after-load 'acm
  (setq acm-backebd-lsp-enable-auto-import t)

  (define-key acm-mode-map (kbd "<escape>") #'acm-hide)
  (define-key acm-mode-map (kbd "M-k") #'acm-select-prev)
  (define-key acm-mode-map (kbd "TAB") #'acm-select-next)
  (define-key acm-mode-map [tab] #'acm-select-next)
  (define-key acm-mode-map (kbd "S-TAB") #'acm-select-prev)
  (define-key acm-mode-map [backtab] #'acm-select-prev)
  (define-key acm-mode-map (kbd "<f2>") #'acm-doc-scroll-up)
  (define-key acm-mode-map (kbd "<f3>") #'acm-doc-scroll-down)
  (define-key acm-mode-map (kbd "M-t") #'acm-doc-toggle)


  (defun ctrlwei/acm-select-advice-func (&rest args)
    (interactive)
    (let ((old-index acm-menu-index)
          (old-offset acm-menu-offset))
      (cond ((eql (length acm-menu-candidates) 1)
             (acm-complete))
            (t
             (apply args)
             (when (and (= old-index acm-menu-index)
                        (= old-offset acm-menu-offset))
               (if (= old-index 0)
                   (acm-select-last)
                 (acm-select-first)))))))
  (advice-add 'acm-select-prev :around 'ctrlwei/acm-select-advice-func)
  (advice-add 'acm-select-next :around 'ctrlwei/acm-select-advice-func)
  )

(with-eval-after-load 'acm-quick-access
  (setq acm-enable-quick-access t))

(provide 'init-lsp-bridge)
;; init-lsp-bridge ends here
